package ca.etsmtl.log430.lab3.sysB;



import java.io.*;
import java.util.*;

/**
 * This class is intended to be a filter that will send the information on an output pipe
 * specific to each project type. In other terms, this filter splits the data by project type.
 * <br><br>
 * 
 * <pre>
 * Pseudo Code:
 *
 * connect to input pipe
 * connect to output pipe
 *
 * while not end of line
 *     if REG appears on line of text 
 *         write line of text to REG output pipe
 *         flush pipe
 *     else if CRI appears on line of text
 *         write line of text to CRI output pipe
 *         flush pipe
 *     end if
 * end while
 * 
 * close pipes
 * </pre>
 *
 * @author R. Champagne
 * @version 1.0
 */

public class StatusFilter extends Thread {
	
	boolean done;
	PipedReader inputPipe = new PipedReader();
	List<PipedWriter> outputsPipeREG = new ArrayList<PipedWriter>();
	List<PipedWriter> outputsPipeCRI = new ArrayList<PipedWriter>();

	public StatusFilter(PipedWriter inputPipe, List<PipedWriter> outputsPipeREG, List<PipedWriter> outputsPipeCRI) {
		try {
			// Connect inputPipe
 			this.inputPipe.connect(inputPipe);
			System.out.println("StatusFilter:: connected to upstream filter.");

			// Connect OutputPipes
			this.outputsPipeREG = outputsPipeREG;
			this.outputsPipeCRI = outputsPipeCRI;
			System.out.println("StatusFilter:: connected to downstream filters.");

		} catch (Exception Error) {
			System.out.println("StatusFilter:: Error connecting to other filters.");
		}
	}
	
	// This is the method that is called when the thread is started
	public void run() {
		char[] characterValue = new char[1];
		// char array is required to turn char into a string
		String lineOfText = "";
		// string is required to look for the status code
		int integerCharacter; // the integer value read from the pipe

		try {
			done = false;

			while (!done) {
				integerCharacter = inputPipe.read();
				characterValue[0] = (char) integerCharacter;

				if (integerCharacter == -1) { // pipe is closed
					done = true;
				} else {
					if (integerCharacter == '\n') { // end of line

						System.out.println("StatusFilter:: received: " + lineOfText + ".");

						if (lineOfText.startsWith("REG ")) {
							System.out.println("StatusFilter:: sending: " + lineOfText + " to output pipe 1 (REG).");
							lineOfText += new String(characterValue);
							
							java.util.Iterator<PipedWriter> ite = outputsPipeREG.iterator();
							while(ite.hasNext())
							{
								PipedWriter outputPipe = ite.next();
								outputPipe.write(lineOfText, 0, lineOfText.length());
								outputPipe.flush();
							}

						} else if(lineOfText.startsWith("CRI ")) {
							System.out.println("StatusFilter:: sending: " + lineOfText + " to output pipe 2 (CRI).");
							lineOfText += new String(characterValue);
							
							java.util.Iterator<PipedWriter> ite = outputsPipeCRI.iterator();
							while(ite.hasNext())
							{
								PipedWriter outputPipe = ite.next();
								outputPipe.write(lineOfText, 0, lineOfText.length());
								outputPipe.flush();
							}
 						}
						
						lineOfText = "";
					} else {
						lineOfText += new String(characterValue);
					}
				}
			}
		} catch (Exception error) {
			System.out.println("StatusFilter:: Interrupted.");
			error.printStackTrace();
		}

		try {
			inputPipe.close();
			System.out.println("StatusFilter:: input pipe closed.");
				
			java.util.Iterator<PipedWriter> ite1 = outputsPipeREG.iterator();
			while(ite1.hasNext())
			{
				PipedWriter outputPipe = ite1.next();
				outputPipe.close();
			}
			
			java.util.Iterator<PipedWriter> ite2 = outputsPipeCRI.iterator();
			while(ite2.hasNext())
			{
				PipedWriter outputPipe = ite2.next();
				outputPipe.close();
			}
			
			System.out.println("StatusFilter:: output pipes closed.");
		} catch (Exception Error) {
			System.out.println("StatusFilter:: Error closing pipes.");
		}
	}
}